package com.zondy.mapgis.psmap.manager.controller;

import cn.hutool.http.HttpUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.zondy.mapgis.common.controllerprefix.annotation.ServicesRestController;
import com.zondy.mapgis.common.core.utils.JsonUtils;
import com.zondy.mapgis.common.core.utils.StringUtils;
import com.zondy.mapgis.common.core.utils.file.FileUtils;
import com.zondy.mapgis.common.log.annotation.Log;
import com.zondy.mapgis.common.log.enums.BusinessType;
import com.zondy.mapgis.common.security.utils.SecurityUtils;
import com.zondy.mapgis.config.properties.FileProperties;
import com.zondy.mapgis.domain.psmap.AppStore;
import com.zondy.mapgis.domain.psmap.AppStoreWidget;
import com.zondy.mapgis.domain.psmap.AppTheme;
import com.zondy.mapgis.domain.psmap.AppWidget;
import com.zondy.mapgis.domain.psmap.vo.AppConfigVo;
import com.zondy.mapgis.domain.psmap.vo.AppWidgetConfigVo;
import com.zondy.mapgis.domain.psmap.vo.ConfigVo;
import com.zondy.mapgis.psmap.manager.service.IAppStoreService;
import com.zondy.mapgis.psmap.manager.service.IAppStoreWidgetService;
import com.zondy.mapgis.psmap.manager.service.IAppThemeService;
import com.zondy.mapgis.psmap.manager.service.IAppWidgetService;
import com.zondy.mapgis.system.api.service.SysServiceProxy;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

@Tag(
        name = "应用资源服务管理",
        description = "应用资源服务控制器"
)
@ServicesRestController({"/system/AppResourceServer"})
public class AppResourceServerController {
    private final IAppStoreService appStoreService;
    private final IAppStoreWidgetService appStoreWidgetService;
    private final IAppWidgetService appWidgetService;
    private final IAppThemeService appThemeService;
    private final SysServiceProxy sysServiceProxy;
    private final FileProperties fileProperties;

    @Operation(
            summary = "获取应用配置信息"
    )
    @GetMapping({"/app/config"})
    public ResponseEntity<Object> getAppConfig() {
        Long userId = SecurityUtils.getUserId();
        return new ResponseEntity<>(this.appStoreService.fillupAppStore(this.appStoreService.selectAppStoreByAppId(1L), userId), HttpStatus.OK);
    }

    @Operation(
            summary = "修改应用配置信息"
    )
    @Log(
            title = "应用",
            businessType = BusinessType.UPDATE
    )
    @PutMapping({"/app/config"})
    public ResponseEntity<Object> editAppConfig(@RequestBody AppConfigVo appConfigVo) {
        AppStore appStore = new AppStore();
        appStore.setAppId(1L);
        appStore.setAppConfig(this.appStoreService.extractAppStore(appConfigVo.getConfig(), SecurityUtils.getUsername()));
        appStore.setUpdateBy(SecurityUtils.getUsername());
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @Operation(
            summary = "获取应用的单个微件配置"
    )
    @GetMapping({"/app/widgetConfig"})
    public ResponseEntity getAppWidgetConfig(@RequestParam String name) {
        AppStoreWidget appStoreWidget = this.appStoreService.getAppWidget("", name);
        return StringUtils.isNull(appStoreWidget)
                ? new ResponseEntity<>(null, HttpStatus.OK)
                : new ResponseEntity<>(this.appStoreService.getAppWidgetConfig(appStoreWidget), HttpStatus.OK);
    }

    @Operation(
            summary = "修改应用的单个微件配置"
    )
    @Log(
            title = "应用",
            businessType = BusinessType.UPDATE
    )
    @PutMapping({"/app/widgetConfig"})
    public ResponseEntity<Object> updateAppWidgetConfig(@Validated @RequestBody AppWidgetConfigVo appWidgetConfigVo) {
        AppStoreWidget appStoreWidget = new AppStoreWidget();
        appStoreWidget.setWidget(new AppWidget());
        appStoreWidget.getWidget().setWidgetName(appWidgetConfigVo.getName());
        appStoreWidget.setAppWidgetConfig(appWidgetConfigVo.getConfig());
        appStoreWidget.setUpdateBy(SecurityUtils.getUsername());
        this.appStoreWidgetService.updateAppStoreWidget(appStoreWidget);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @Operation(
            summary = "获取单个公共配置"
    )
    @GetMapping({"/configs/{name}"})
    public ResponseEntity<Object> getConfigValue(@PathVariable String name) {
        Map<String, String> appConfigKey2SysConfigKey = new HashMap<>();
        String configValue = "";
        Object configValueObject;
        appConfigKey2SysConfigKey.put("district", "system.district");
        appConfigKey2SysConfigKey.put("sheet", "system.mapsheet");
        appConfigKey2SysConfigKey.put("nospatial", "system.nospatial");
        if ("base".equals(name)) {
            String[] sysConfigKeys = new String[]{"app.server", "app.display", "app.srs", "app.plot", "app.dataIcons"};
            JsonNode mergedInTo = JsonUtils.toJsonNode(this.sysServiceProxy.selectConfigValueByKey(sysConfigKeys[0]));

            for (int i = 1; i < sysConfigKeys.length; ++i) {
                JsonNode toBeMerged = JsonUtils.toJsonNode(this.sysServiceProxy.selectConfigValueByKey(sysConfigKeys[i]));
                JsonUtils.merge(toBeMerged, mergedInTo);
            }

            configValue = mergedInTo.toString();
        } else if (appConfigKey2SysConfigKey.containsKey(name)) {
            configValue = this.sysServiceProxy.selectConfigValueByKey(appConfigKey2SysConfigKey.get(name), "{}");
        }

        if (configValue.startsWith("[")) {
            configValueObject = JsonUtils.parseArrayMap(configValue);
        } else {
            configValueObject = JsonUtils.parseMap(configValue);
        }

        return new ResponseEntity<>(configValueObject, HttpStatus.OK);
    }

    @Operation(
            summary = "修改单个公共配置"
    )
    @Log(
            title = "应用",
            businessType = BusinessType.UPDATE
    )
    @PutMapping({"/configs/"})
    public ResponseEntity<Object> updateConfigValue(@RequestBody ConfigVo configVo) {
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }

    @Operation(
            summary = "获取主题集合"
    )
    @GetMapping({"/themes"})
    public ResponseEntity<Object> getThemes() {
        return new ResponseEntity(this.appThemeService.selectAppThemeList(new AppTheme()), HttpStatus.OK);
    }

    @Operation(
            summary = "获取主题清单信息"
    )
    @GetMapping({"/themes/{themeName}/manifest.json"})
    public ResponseEntity<Object> getThemeManifest(@PathVariable String themeName) {
        AppTheme appTheme = this.appThemeService.selectAppThemeByThemeName(themeName);
        return StringUtils.isNull(appTheme)
                ? new ResponseEntity(HttpStatus.NO_CONTENT)
                : new ResponseEntity(appTheme.getManifest(), HttpStatus.OK);
    }

    @Operation(
            summary = "获取主题布局信息"
    )
    @GetMapping({"/themes/{themeName}/layout.json"})
    public ResponseEntity<Object> getThemeLayout(@PathVariable String themeName) {
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }

    @Operation(
            summary = "获取微件集合"
    )
    @GetMapping({"/widgets"})
    public ResponseEntity<Object> getWidgets() {
        return new ResponseEntity(this.appWidgetService.selectAppWidgetList(new AppWidget()), HttpStatus.OK);
    }

    @Operation(
            summary = "获取微件清单信息"
    )
    @GetMapping({"/widgets/{widgetName}/manifest.json"})
    public ResponseEntity<Object> getWidgetManifest(@PathVariable String widgetName) {
        AppWidget appWidget = this.appWidgetService.selectAppWidgetByWidgetName(widgetName);
        return StringUtils.isNull(appWidget)
                ? new ResponseEntity(HttpStatus.NO_CONTENT)
                : new ResponseEntity(appWidget.getManifest(), HttpStatus.OK);
    }

    @Operation(
            summary = "获取微件默认配置信息"
    )
    @GetMapping({"/widgets/{widgetName}/config.json"})
    public ResponseEntity<Object> getWidgetDefaultConfig(@PathVariable String widgetName) {
        AppWidget appWidget = this.appWidgetService.selectAppWidgetByWidgetName(widgetName);
        return StringUtils.isNull(appWidget) ? new ResponseEntity(HttpStatus.NO_CONTENT) : new ResponseEntity(appWidget.getConfig(), HttpStatus.OK);
    }

    @Operation(
            summary = "获取微件默认图片资源"
    )
    @GetMapping({"/widgets/{widgetName}/images/{image}"})
    public void getWidgetDefaultImage(HttpServletResponse response, @PathVariable String widgetName, @PathVariable String image) {
        this.getAppFileResource(response, "widgets", widgetName, "images" + File.separator + image);
    }

    @Operation(
            summary = "获取微件自定义配置信息"
    )
    @GetMapping({"/configs/{widgetName}/config.json"})
    public ResponseEntity<Object> getWidgetCustomConfig(@PathVariable String widgetName) {
        AppStoreWidget appStoreWidget = this.appStoreWidgetService.selectAppStoreWidgetByWidgetName(widgetName);
        return StringUtils.isNull(appStoreWidget) ? new ResponseEntity(HttpStatus.NO_CONTENT) : new ResponseEntity(appStoreWidget.getAppWidgetConfig(), HttpStatus.OK);
    }

    @Operation(
            summary = "获取微件资源"
    )
    @GetMapping({"/widgets/{widgetName}/{widgetFileResource}"})
    public void getWidgetFileResource(HttpServletResponse response, @PathVariable String widgetName, @PathVariable String widgetFileResource) {
        this.getAppFileResource(response, "widgets", widgetName, widgetFileResource);
    }

    @Operation(
            summary = "获取主题资源"
    )
    @GetMapping({"/themes/{themeName}/{themeFileResource}"})
    public void getThemeFileResource(HttpServletResponse response, @PathVariable String themeName, @PathVariable String themeFileResource) {
        this.getAppFileResource(response, "themes", themeName, themeFileResource);
    }

    @Operation(
            summary = "获取主题默认图片资源"
    )
    @GetMapping({"/themes/{themeName}/images/{image}"})
    public void getThemeDefaultImage(HttpServletResponse response, @PathVariable String themeName, @PathVariable String image) {
        this.getAppFileResource(response, "themes", themeName, "images" + File.separator + image);
    }

    private void getAppFileResource(HttpServletResponse response, String resourceType, String resourcePath, String resourceName) {
        String fileFullPath = Paths.get(this.fileProperties.getFullDataPath(), resourceType, resourcePath, resourceName).normalize().toString();
        File file = new File(fileFullPath);
        if (!file.exists()) {
            fileFullPath = Paths.get(this.fileProperties.getFullPath(), "default", resourceType, resourcePath, resourceName).normalize().toString();
            file = new File(fileFullPath);
        }

        if (file.exists()) {
            try {
                response.setContentType(HttpUtil.getMimeType(file.getPath()));
                FileUtils.writeBytes(fileFullPath, response.getOutputStream());
            } catch (IOException var8) {
                var8.printStackTrace();
            }
        } else {
            response.setStatus(204);
        }

    }

    @Autowired
    public AppResourceServerController(IAppStoreService appStoreService, IAppStoreWidgetService appStoreWidgetService, IAppWidgetService appWidgetService, IAppThemeService appThemeService, SysServiceProxy sysServiceProxy, FileProperties fileProperties) {
        this.appStoreService = appStoreService;
        this.appStoreWidgetService = appStoreWidgetService;
        this.appWidgetService = appWidgetService;
        this.appThemeService = appThemeService;
        this.sysServiceProxy = sysServiceProxy;
        this.fileProperties = fileProperties;
    }
}
